﻿using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace VisualPureBasicIDE.CoreGUI
{
    public class AeroManager
    {
        private readonly Form _form;
        private Margins _margins;

        /// <summary>
        /// The struct used to pass the Glass margins to the Win32 API
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        public struct Margins
        {
            public int Left;
            public int Right;
            public int Top;
            public int Bottom;
        }

        /// <summary>
        /// The API used to extend the Glass margins into the client area
        /// </summary>
        [DllImport("dwmapi.dll", PreserveSig = false)]
        private static extern void DwmExtendFrameIntoClientArea(IntPtr hwnd, ref Margins margins);

        /// <summary>
        /// Determins whether the Desktop Windows Manager is enabled
        /// and can therefore display Aero 
        /// </summary>
        [DllImport("dwmapi.dll", PreserveSig = false)]
        private static extern bool DwmIsCompositionEnabled();

        public AeroManager(Form form, Margins margins)
        {
            if (Environment.OSVersion.Platform != PlatformID.Win32NT || Environment.OSVersion.Version.Major < 6 || !DwmIsCompositionEnabled())
                throw new NotSupportedException("Applying glass to forms without using Windows Vista or better is not supported. Also make sure, you enabled DWM composition.");

            _form = form;
            _margins = margins;

            _form.TransparencyKey = Color.Gainsboro;

            _form.Load += Form_Load;
            _form.Paint += Form_Paint;
        }

        void Form_Load(object sender, EventArgs e)
        {
            SetGlassRegion();
        }

        void Form_Paint(object sender, PaintEventArgs e)
        {
            if (DwmIsCompositionEnabled())
            {
                e.Graphics.Clear(Color.Gainsboro);

                // Put back the original form background for non-glass area
                var clientArea = new Rectangle(
                _margins.Left,
                _margins.Top,
                _form.ClientRectangle.Width - _margins.Left - _margins.Right,
                _form.ClientRectangle.Height - _margins.Top - _margins.Bottom);

                Brush b = new SolidBrush(_form.BackColor);

                e.Graphics.FillRectangle(b, clientArea);
            }
        }

        public Margins GlassArea
        {
            get
            {
                return _margins;
            }
            set
            {
                _margins = value;
                SetGlassRegion();
            }
        }

        /// <summary>
        /// Use the form padding values to define a Glass margin
        /// </summary>
        private void SetGlassRegion()
        {
            // Set up the glass effect using padding as the defining glass region
            if (DwmIsCompositionEnabled())
                DwmExtendFrameIntoClientArea(_form.Handle, ref _margins);
        }
    }
}
